Skip to content

Conversation

@sniperrifle2004
Copy link

@sniperrifle2004 sniperrifle2004 commented Jun 19, 2020

I have taken the alsa pcm's approach of a period of the buffer size for playback. Hopefully that fills up the buffer since the next period is coming shortly and can probably be written well within the time it takes to play the first period in the buffer. I don't know if this assumption holds in extremely low latency situations, but if it doesn't I suspect underruns would start happening anyway.

Fixes #432

@sniperrifle2004 sniperrifle2004 changed the title Set appropriate start threshold depending on the direction [Alsa Host] Set appropriate start threshold depending on the direction Jun 19, 2020
@sniperrifle2004 sniperrifle2004 force-pushed the set-start_threshold-based-on-direction branch from 1824c9c to 656b568 Compare June 19, 2020 16:18
@sniperrifle2004 sniperrifle2004 marked this pull request as draft June 24, 2020 11:31
This is caused by the way poll_descriptors_and_prepare_buffer
defers the read and write and essentially defers the read
indefinitely and that causes the start to be deferred
indefinitely. So the pcm will be started explicitly for
capture. Buffer underruns aren't a problem for
capture streams anyway
@mitchmindtree
Copy link
Member

Thanks for diving into this! And thanks for taking a close look into the ALSA backend in general - I've already learned a few new things reading through your recent comments/PRs.

Perhaps we should land #401 first and then base this work on top of that?

@sniperrifle2004
Copy link
Author

sniperrifle2004 commented Jun 24, 2020

I'm fine with that. I am still doing some research into this at the moment. It appears that on my machine the fact that poll_descriptors_and_prepare_buffer requests a (nearly) full buffer of frames the first time is sufficient to prevent buffer underruns even with the pcm starting while no data is available in the buffer. However whether this will always be the case is harder to say. It's not something I personally would want to rely on given my current understanding of the semantics, but it might also mean that I have misunderstood something in the semantics and that this is actually perfectly fine (provided the application is able to provide the initial buffer contents fast enough).

@sniperrifle2004
Copy link
Author

It appears that on my machine the fact that poll_descriptors_and_prepare_buffer requests a (nearly) full buffer of frames the first time is sufficient to prevent buffer underruns even with the pcm starting while no data is available in the buffer.

That hypothesis can be scrapped. My understanding of the semantics involved was correct. I can now confirm that this will definitely result in under-runs. In fact it happens immediately at the handle.start() if you talk directly to a hardware device. So it's likely that features on the software level have been helpfully hiding this problem to some extend. Plugins like pulse/dmix/plug a lot of cards have for the (sys)default configuration. That might also explain why my less powerful system was stuttering despite not showing under-runs: Under-runs were occurring just not at the cpal level. I have now also reproduced this by talking to the hw:0,0 device on my regular system: Immediate under-run.

// if the pcm is not started
if stream_type == alsa::Direction::Capture {
handle.start()?
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you set the start_threshold for capture streams to 1, I think you would not have to call start() here at all.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexmoon any chance you might be interested in getting this work over the line in a new PR? My understanding on this is a bit vague, but it sounds like this might help with some of the initial underruns that can occur when kicking off an ALSA stream?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mitchmindtree yes, I can work on that. I'd probably like to combine this change with #431 since they're related and wait until #506 is merged so we don't have too many outstanding PRs touching the same files.

Copy link
Author

@sniperrifle2004 sniperrifle2004 Dec 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexmoon You may be right. I vaguely recall trying 1 and it not working. I then hypothesized that it was due to readi not getting called at all if the pcm is not running and the start_threshold for recording relying on that to switch the pcm to running. But that memory is shaky at best and I am not an expert.

Copy link
Author

@sniperrifle2004 sniperrifle2004 Dec 8, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@alexmoon Well it seems like I actually have some evidence to back up that memory in commit 3d1ecbe . The log message also goes into the technical details of the hypothesis. Note also that I thought it worked in the earlier commit since I had not actually removed the handle.start()? yet.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that seems to be correct. In my other implementation I was using readi() and a start_threshold of 1 worked correctly.

@sniperrifle2004
Copy link
Author

Superseded by #520

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Alsa Host] Start threshold of 0

3 participants